package com.three.aop;

import com.alibaba.fastjson2.JSON;
import com.three.entity.OperLog;
import com.three.entity.Staff;
import com.three.mapper.OperLogMapper;
import com.three.service.OperLogService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;

@Component
@Aspect// 表示这是一个切面
public class LogAspect {
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private OperLogMapper operLogMapper;

    //切点
    @Pointcut("@annotation(com.three.aop.LogAnotation)") //解释：匹配所有被LogAnotation注解的方法
    public void pointCut(){
    }

    //绕环通知
    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        //创建一个日志对象
        OperLog operLog = new OperLog();
        String method = joinPoint.getSignature().getName();//获取方法名
        operLog.setMethod(method);//设置方法名
        String method1 = request.getMethod();//获取请求方式
        operLog.setRequestmethod(method1);//设置请求方式
        HttpSession session = request.getSession();
        Staff staff = (Staff) session.getAttribute("staff");
        operLog.setOpername(staff.getStaffname());//设置操作人
        operLog.setOperurl(request.getRequestURI());//设置请求路径
        String remoteAddr = request.getRemoteAddr();
        operLog.setOperip(remoteAddr);//设置ip地址

        Object[] args = joinPoint.getArgs();//获取参数
        String param = Arrays.toString(args);//转为字符串
        operLog.setOperparam(param);//设置参数
        operLog.setOpertime(new Date());//设置时间
        operLog.setStatus(0);//设置状态

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method2 = signature.getMethod();//获取方法对象
        LogAnotation loAnotation = method2.getAnnotation(LogAnotation.class);//获取注解对象
        String value = loAnotation.value();//获取注解的值
        operLog.setBusinesstype(value);//设置业务类型
        try{
            Object proceed = joinPoint.proceed();//执行方法
            String s = JSON.toJSONString(proceed);
            operLog.setJsonresult(s);//设置返回值
            return proceed;
        }catch (Exception e){
            operLog.setStatus(1);
            throw e;
        }finally {
            //添加日志
            operLogMapper.insertSelective(operLog);
            if (operLog.getStatus()==0){
                //添加日志成功
                operLog.setStatus(1);
            }
        }
    }
}
